package com.bsoft.gol.hcs.clinical.dao;

import ctd.persistence.annotation.DAOMethod;
import ctd.persistence.annotation.DAOParam;
import ctd.persistence.support.hibernate.HibernateSupportDelegateDAO;
import ctd.persistence.support.hibernate.template.AbstractHibernateStatelessResultAction;
import ctd.persistence.support.hibernate.template.HibernateSessionTemplate;
import ctd.persistence.support.hibernate.template.HibernateStatelessResultAction;
import ctd.util.converter.ConversionUtils;
import hcn.base.drug.BaseFactory;
import hcn.protocol.BaseFactoryRequestBean;
import hcn.protocol.ods.BaseFactoryVO;
import hcn.util.validation.StringUtil;
import org.hibernate.Query;
import org.hibernate.StatelessSession;
import org.hibernate.criterion.CriteriaSpecification;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public abstract class BaseFactoryDAO extends HibernateSupportDelegateDAO<BaseFactory> {

    public BaseFactoryDAO() {
        this.setKeyField("factoryId");
    }

    @DAOMethod(sql = " from BaseFactory where factoryCode =:factoryCode")
    public abstract BaseFactory getBaseFactoryByCode(@DAOParam("factoryCode")String factoryCode);

    @DAOMethod(sql= " from BaseFactory where status= 1")
    public abstract List<BaseFactory> findBaseFacetory();

    public List<BaseFactoryVO> findFactoryByPage(BaseFactoryRequestBean request) {
        HibernateStatelessResultAction<List<BaseFactoryVO>> action = new AbstractHibernateStatelessResultAction<List<BaseFactoryVO>>() {

            @Override
            public void execute(StatelessSession statelessSession) throws Exception {
                String sql = executeSetCountSQL(request);
                Query sqlQuery = statelessSession.createSQLQuery(sql);
                int first = request.getPageNo() > 0 ? (request.getPageNo() - 1) * request.getPageSize() : 0;
                sqlQuery.setFirstResult(first);
                sqlQuery.setMaxResults(request.getPageSize());
                sqlQuery.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map> dbList = sqlQuery.list();
                List<BaseFactoryVO> baseFactoryVOS = new ArrayList<>();
                for (Map map : dbList) {
                    baseFactoryVOS.add(ConversionUtils.convert(map, BaseFactoryVO.class));
                }
                setResult(baseFactoryVOS);
            }

            private String executeSetCountSQL(BaseFactoryRequestBean request){
                StringBuilder sql = new StringBuilder("select factory_id as id,factory_code as factoryCode,factory_name as factoryName,short_name as shortName,pinyin_code as pinyinCode,status from base_factory where delete_status='0' ");
                if (!StringUtil.isEmpty(request.getShortName())){
                    sql.append("and short_name like '%"+request.getShortName()+"%' ");
                }
                if (!StringUtil.isEmpty(request.getPinyinCode())){
                    sql.append("and pinyin_code like '%"+request.getPinyinCode()+"%' ");
                }
                if (!StringUtil.isEmpty(request.getStatus())){
                    sql.append("and status = '"+request.getStatus().trim()+"' ");
                }
//                sql.append("order by create_dt desc;");
                return sql.toString();
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    public BigInteger findFactoryCountByPage(BaseFactoryRequestBean request){
        HibernateStatelessResultAction<BigInteger> action = new AbstractHibernateStatelessResultAction<BigInteger>() {

            @Override
            public void execute(StatelessSession statelessSession) throws Exception {
                String sql = executeSetCountSQL(request);
                Query sqlQuery = statelessSession.createSQLQuery(sql);
//                int first = request.getPageNo() > 0 ? (request.getPageNo() - 1) * request.getPageSize() : 0;
//                sqlQuery.setFirstResult(first);
//                sqlQuery.setMaxResults(request.getPageSize());
                    List list = sqlQuery.list();
                    if (list.size() == 1) {
                        Object o = list.get(0);
                        BigInteger count = (BigInteger) o;
                        setResult(count);
                }
            }

            private String executeSetCountSQL(BaseFactoryRequestBean request){
                StringBuilder sql = new StringBuilder("select count(1) from base_factory where delete_status='0' ");
                if (!StringUtil.isEmpty(request.getShortName())){
                    sql.append("and short_name like '%"+request.getShortName()+"%' ");
                }
                if (!StringUtil.isEmpty(request.getPinyinCode())){
                    sql.append("and pinyin_code like '%"+request.getPinyinCode()+"%' ");
                }
                if (!StringUtil.isEmpty(request.getStatus())){
                    sql.append("and status = '"+request.getStatus().trim()+"' ");
                }
                return sql.toString();
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    public int getByFactoryNameOrCode(String factoryName, String factoryCode){
        HibernateStatelessResultAction<Integer> action = new AbstractHibernateStatelessResultAction<Integer>() {

            @Override
            public void execute(StatelessSession statelessSession) throws Exception {
                String sql = executeSetCountSQL(factoryName,factoryCode);
                Query sqlQuery = statelessSession.createSQLQuery(sql);
                if (!StringUtil.isEmpty(factoryName)){
                    sqlQuery.setParameter("factoryName",factoryName);
                }
                if (!StringUtil.isEmpty(factoryName) && !StringUtil.isEmpty(factoryCode)){
                    sqlQuery.setParameter("factoryCode",factoryCode);
                }
                if (StringUtil.isEmpty(factoryName) && !StringUtil.isEmpty(factoryCode)){
                    sqlQuery.setParameter("factoryCode",factoryCode);
                }
                List list = sqlQuery.list();
                if (list.size() == 1) {
                    Object o = list.get(0);
                    BigInteger count = (BigInteger) o;
                    setResult(count.intValue());
                }
            }

            private String executeSetCountSQL(String factoryName,String factoryCode){
                StringBuilder sql = new StringBuilder("select count(1) from base_factory where delete_status='0'");
                if (!StringUtil.isEmpty(factoryName)){
                    sql.append("and factory_name=:factoryName ");
                }
                if (!StringUtil.isEmpty(factoryName) && !StringUtil.isEmpty(factoryCode)){
                    sql.append("or factory_code=:factoryCode");
                }
                if (StringUtil.isEmpty(factoryName) && !StringUtil.isEmpty(factoryCode)){
                    sql.append("and factory_code=:factoryCode");
                }
                return sql.toString();
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    public int getByFactoryNameOrCode(BaseFactory factory, String factoryName, String factoryCode){
        HibernateStatelessResultAction<Integer> action = new AbstractHibernateStatelessResultAction<Integer>() {

            @Override
            public void execute(StatelessSession statelessSession) throws Exception {
                String sql = executeSetCountSQL(factoryName,factoryCode);
                Query sqlQuery = statelessSession.createSQLQuery(sql);
                if (!StringUtil.isEmpty(factoryName)){
                    sqlQuery.setParameter("factoryName",factoryName);
                }
                if (!StringUtil.isEmpty(factoryName) && !StringUtil.isEmpty(factoryCode)){
                    sqlQuery.setParameter("factoryCode",factoryCode);
                }
                if (StringUtil.isEmpty(factoryName) && !StringUtil.isEmpty(factoryCode)){
                    sqlQuery.setParameter("factoryCode",factoryCode);
                }
                sqlQuery.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map> list = sqlQuery.list();
                int i = 0;
                for (Map map : list) {
                    int factoryId = (int) map.get("factory_id");
                    if (factory.getFactoryId() == factoryId) {
                        continue;
                    }
                    i++;
                }
                setResult(i);
            }

            private String executeSetCountSQL(String factoryName,String factoryCode){
                StringBuilder sql = new StringBuilder("select factory_code,factory_name,factory_id from base_factory where delete_status='0'");
                if (!StringUtil.isEmpty(factoryName)){
                    sql.append("and factory_name=:factoryName ");
                }
                if (!StringUtil.isEmpty(factoryName) && !StringUtil.isEmpty(factoryCode)){
                    sql.append("or factory_code=:factoryCode");
                }
                if (StringUtil.isEmpty(factoryName) && !StringUtil.isEmpty(factoryCode)){
                    sql.append("and factory_code=:factoryCode");
                }
                return sql.toString();
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }
}
